﻿
// **************************************************************************
//    Class Created by Mick Doherty (Dotnetrix) May 2010
//    http://dotnetrix.co.uk/
//
//    ...for GlassUI (an AeroGlass UI Library)
//    http://glassui.codeplex.com/
// **************************************************************************

using System.Runtime.InteropServices;
using System;
using System.Globalization;
using System.Drawing;
using System.Windows.Forms;

namespace GlassUI
{
    internal sealed partial class NativeMethods
    {
        internal sealed class COMCTL32
        {
            private COMCTL32() { }

            #region Method Imports

            [DllImport("comctl32.dll", ExactSpelling = true, SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool _TrackMouseEvent(ref NativeMethods.USER32.TRACKMOUSEEVENT tme);

            #endregion

            #region Structures

            [StructLayout(LayoutKind.Sequential)]
            public struct LVGROUP : IDisposable
            {
                public int cbSize;
                public LVGROUPMASK mask;
                public IntPtr pszHeader;
                public int cchHeader;
                public IntPtr pszFooter;
                public int cchFooter, iGroupId;
                public LVGROUPSTATE stateMask, state;
                public LVGROUPALIGN uAlign;

                #region IDisposable Members

                public void Dispose()
                {
                    if (pszHeader != null)
                        Marshal.FreeHGlobal(pszHeader);
                    if (pszFooter != null)
                        Marshal.FreeHGlobal(pszFooter);
                }

                #endregion
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct LVGROUPMETRICS
            {
                public int cbSize;
                public int mask;
                public int Left;
                public int Top;
                public int Right;
                public int Bottom;
                public int crLeft;
                public int crTop;
                public int crRight;
                public int crBottom;
                public int crHeader;
                public int crFooter;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct NMHDR
            {
                public IntPtr HWND;
                public int idFrom;
                public int code;
                public override String ToString()
                {
                    return String.Format(CultureInfo.CurrentCulture, "Hwnd: {0}, ControlID: {1}, Code: {2}", HWND, idFrom, code);
                }
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct NMCUSTOMDRAW
            {
                public NMHDR hdr;
                public CustomDrawDrawStage dwDrawStage;
                public IntPtr hdc;
                public USER32.RECT rc;
                public IntPtr dwItemSpec;
                public CustomDrawItemState uItemState;
                public IntPtr lItemlParam;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct NMLVCUSTOMDRAW
            {
                public NMCUSTOMDRAW nmcd;
                public int clrText;
                public int clrTextBk;
                public int iSubItem;
                public int dwItemType;
                public int clrFace;
                public int iIconEffect;
                public int iIconPhase;
                public int iPartId;
                public int iStateId;
                public USER32.RECT rcText;
                public int uAlign;
            }  

            [StructLayout(LayoutKind.Sequential)]
            public struct HDITEM 
            {
                public int mask;
                public int cxy;
                public IntPtr pszText;
                public IntPtr hbm;
                public int cchTextMax;
                public int fmt;
                public IntPtr lParam;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct LVCOLUMN
            {
                public int mask, fmt, cx;
                public IntPtr pszText;
                public int cchTextMax, iSubItem;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct DRAWITEMSTRUCT
            {
                public int CtlType, CtlID, itemID, itemAction;
                public ListViewItemStates itemState;
                public IntPtr hwndItem, hDC;
                public USER32.RECT rcItem;
                public IntPtr itemData;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct LVHITTESTINFO
            {
                public Point pt;
                public ListViewHitTestResult flags;
                public int iItem, iSubItem, iGroup;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct HDHITTESTINFO
            {
                public Point pt;
                public HeaderHitTestResult  flags;
                public int iItem;
            } 

            #endregion

            #region Enumerations

            [Flags]
            public enum LVGROUPMASK
            {
                LVGF_NONE,
                LVGF_HEADER,
                LVGF_FOOTER,
                LVGF_STATE = 0x00000004,
                LVGF_ALIGN = 0x00000008,
                LVGF_GROUPID = 0x00000010,
                // Vista and above
                LVGF_SUBTITLE = 0x00000100,  // pszSubtitle is valid
                LVGF_TASK = 0x00000200,  // pszTask is valid
                LVGF_DESCRIPTIONTOP = 0x00000400,  // pszDescriptionTop is valid
                LVGF_DESCRIPTIONBOTTOM = 0x00000800,  // pszDescriptionBottom is valid
                LVGF_TITLEIMAGE = 0x00001000,  // iTitleImage is valid
                LVGF_EXTENDEDIMAGE = 0x00002000,  // iExtendedImage is valid
                LVGF_ITEMS = 0x00004000,  // iFirstItem and cItems are valid
                LVGF_SUBSET = 0x00008000,  // pszSubsetTitle is valid
                LVGF_SUBSETITEMS = 0x00010000  // readonly, cItems holds count of items in visible subset, iFirstItem is valid            }
            }

            [Flags]
            public enum LVGROUPSTATE
            {
                LVGS_NORMAL = 0x00000000,
                LVGS_COLLAPSED = 0x00000001,
                LVGS_HIDDEN = 0x00000002,
                LVGS_NOHEADER = 0x00000004,
                LVGS_COLLAPSIBLE = 0x00000008,
                LVGS_FOCUSED = 0x00000010,
                LVGS_SELECTED = 0x00000020,
                LVGS_SUBSETED = 0x00000040,
                LVGS_SUBSETLINKFOCUSED = 0x00000080
            }

            public enum LVGROUPALIGN
            {
                LVGA_HEADER_LEFT = 0x00000001,
                LVGA_HEADER_CENTER = 0x00000002,
                LVGA_HEADER_RIGHT = 0x00000004,  // Don't forget to validate exclusivity
                LVGA_FOOTER_LEFT = 0x00000008,
                LVGA_FOOTER_CENTER = 0x00000010,
                LVGA_FOOTER_RIGHT = 0x00000020  // Don't forget to validate exclusivity            
            }

            public enum LVGETGROUPRECT
            {
                LVGGR_GROUP, // Entire expanded group
                LVGGR_HEADER, // Header only (collapsed group)
                LVGGR_LABEL,  // Label only
                LVGGR_SUBSETLINK  // subset link only
            }

            public enum CustomDrawDrawStage
            {
                CDDS_PREPAINT = 0x1,
                CDDS_POSTPAINT = 0x2,
                CDDS_PREERASE = 0x3,
                CDDS_POSTERASE = 0x4,
                CDDS_ITEM = 0x10000,
                CDDS_ITEMPREPAINT = (CDDS_ITEM | CDDS_PREPAINT),
                CDDS_ITEMPOSTPAINT = (CDDS_ITEM | CDDS_POSTPAINT),
                CDDS_ITEMPREERASE = (CDDS_ITEM | CDDS_PREERASE),
                CDDS_ITEMPOSTERASE = (CDDS_ITEM | CDDS_POSTERASE),
                CDDS_SUBITEM = 0x20000
            }

            public enum CustomDrawItemState
            {
                CDIS_SELECTED = 0x1,
                CDIS_GRAYED = 0x2,
                CDIS_DISABLED = 0x4,
                CDIS_CHECKED = 0x8,
                CDIS_FOCUS = 0x10,
                CDIS_DEFAULT = 0x20,
                CDIS_HOT = 0x40,
                CDIS_MARKED = 0x80,
                CDIS_INDETERMINATE = 0x100,
                CDIS_SHOWKEYBOARDCUES = 0x200
            }

            public enum HeaderControlMessage
            {
                HDM_GETITEMCOUNT = (HDM_FIRST + 0),
                HDM_INSERTITEMA = (HDM_FIRST + 1),
                HDM_INSERTITEMW =(HDM_FIRST + 10),
                HDM_DELETEITEM = (HDM_FIRST + 2),
                HDM_GETITEMA = (HDM_FIRST + 3),
                HDM_GETITEMW = (HDM_FIRST + 11),
                HDM_SETITEMA = (HDM_FIRST + 4),
                HDM_SETITEMW = (HDM_FIRST + 12),
                HDM_LAYOUT = (HDM_FIRST + 5),
                HDM_HITTEST = (HDM_FIRST + 6),
                HDM_GETITEMRECT = (HDM_FIRST + 7),
                HDM_SETIMAGELIST = (HDM_FIRST + 8),
                HDM_GETIMAGELIST = (HDM_FIRST + 9),
                HDM_ORDERTOINDEX = (HDM_FIRST + 15),
                HDM_CREATEDRAGIMAGE = (HDM_FIRST + 16),  // wparam = which item (by index)
                HDM_GETORDERARRAY = (HDM_FIRST + 17),
                HDM_SETORDERARRAY = (HDM_FIRST + 18),
                HDM_SETHOTDIVIDER = (HDM_FIRST + 19),
                HDM_SETBITMAPMARGIN = (HDM_FIRST + 20),
                HDM_GETBITMAPMARGIN = (HDM_FIRST + 21),
                HDM_SETFILTERCHANGETIMEOUT = (HDM_FIRST+22),
                HDM_EDITFILTER = (HDM_FIRST+23),
                HDM_CLEARFILTER = (HDM_FIRST+24),
                HDM_GETITEMDROPDOWNRECT = (HDM_FIRST+25),  // rect of item's drop down button
                HDM_GETOVERFLOWRECT = (HDM_FIRST+26),  // rect of overflow button
                HDM_GETFOCUSEDITEM = (HDM_FIRST+27),
                HDM_SETFOCUSEDITEM = (HDM_FIRST+28)
            }

            public enum ListViewMessage
            {
                LVM_GETBKCOLOR = LVM_FIRST + 0,
                LVM_SETBKCOLOR = LVM_FIRST + 1,
                LVM_GETIMAGELIST = LVM_FIRST + 2,
                LVM_SETIMAGELIST = LVM_FIRST + 3,
                LVM_GETITEMCOUNT = LVM_FIRST + 4,
                LVM_GETITEMA = LVM_FIRST + 5,
                LVM_GETITEMW = LVM_FIRST + 75,
                LVM_SETITEMA = LVM_FIRST + 6,
                LVM_SETITEMW = LVM_FIRST + 76,
                LVM_INSERTITEMA = LVM_FIRST + 7,
                LVM_INSERTITEMW = LVM_FIRST + 77,
                LVM_DELETEITEM = LVM_FIRST + 8,
                LVM_DELETEALLITEMS = LVM_FIRST + 9,
                LVM_GETCALLBACKMASK = LVM_FIRST + 10,
                LVM_SETCALLBACKMASK = LVM_FIRST + 11,
                LVM_GETNEXTITEM = LVM_FIRST + 12,
                LVM_FINDITEMA = LVM_FIRST + 13,
                LVM_FINDITEMW = LVM_FIRST + 83,
                LVM_GETITEMRECT = LVM_FIRST + 14,
                LVM_SETITEMPOSITION = LVM_FIRST + 15,
                LVM_GETITEMPOSITION = LVM_FIRST + 16,
                LVM_GETSTRINGWIDTHA = LVM_FIRST + 17,
                LVM_GETSTRINGWIDTHW = LVM_FIRST + 87,
                LVM_HITTEST = LVM_FIRST + 18,
                LVM_ENSUREVISIBLE = LVM_FIRST + 19,
                LVM_SCROLL = LVM_FIRST + 20,
                LVM_REDRAWITEMS = LVM_FIRST + 21,
                LVM_ARRANGE = LVM_FIRST + 22,
                LVM_EDITLABELA = LVM_FIRST + 23,
                LVM_EDITLABELW = LVM_FIRST + 118,
                LVM_GETEDITCONTROL = LVM_FIRST + 24,
                LVM_GETCOLUMNA = LVM_FIRST + 25,
                LVM_GETCOLUMNW = LVM_FIRST + 95,
                LVM_SETCOLUMNA = LVM_FIRST + 26,
                LVM_SETCOLUMNW = LVM_FIRST + 96,
                LVM_INSERTCOLUMNA = LVM_FIRST + 27,
                LVM_INSERTCOLUMNW = LVM_FIRST + 97,
                LVM_DELETECOLUMN = LVM_FIRST + 28,
                LVM_GETCOLUMNWIDTH = LVM_FIRST + 29,
                LVM_SETCOLUMNWIDTH = LVM_FIRST + 30,
                LVM_GETHEADER = LVM_FIRST + 31,
                LVM_CREATEDRAGIMAGE = LVM_FIRST + 33,
                LVM_GETVIEWRECT = LVM_FIRST + 34,
                LVM_GETTEXTCOLOR = LVM_FIRST + 35,
                LVM_SETTEXTCOLOR = LVM_FIRST + 36,
                LVM_GETTEXTBKCOLOR = LVM_FIRST + 37,
                LVM_SETTEXTBKCOLOR = LVM_FIRST + 38,
                LVM_GETTOPINDEX = LVM_FIRST + 39,
                LVM_GETCOUNTPERPAGE = LVM_FIRST + 40,
                LVM_GETORIGIN = LVM_FIRST + 41,
                LVM_UPDATE = LVM_FIRST + 42,
                LVM_SETITEMSTATE = LVM_FIRST + 43,
                LVM_GETITEMSTATE = LVM_FIRST + 44,
                LVM_GETITEMTEXTA = LVM_FIRST + 45,
                LVM_GETITEMTEXTW = LVM_FIRST + 115,
                LVM_SETITEMTEXTA = LVM_FIRST + 46,
                LVM_SETITEMTEXTW = LVM_FIRST + 116,
                LVM_SETITEMCOUNT = LVM_FIRST + 47,
                LVM_SORTITEMS = LVM_FIRST + 48,
                LVM_SETITEMPOSITION32 = LVM_FIRST + 49,
                LVM_GETSELECTEDCOUNT = LVM_FIRST + 50,
                LVM_GETITEMSPACING = LVM_FIRST + 51,
                LVM_GETISEARCHSTRINGA = LVM_FIRST + 52,
                LVM_GETISEARCHSTRINGW = LVM_FIRST + 117,
                LVM_SETICONSPACING = LVM_FIRST + 53,
                LVM_SETEXTENDEDLISTVIEWSTYLE= LVM_FIRST + 54, // optional wParam == mask
                LVM_GETEXTENDEDLISTVIEWSTYLE= LVM_FIRST + 55,
                LVM_GETSUBITEMRECT = LVM_FIRST + 56,
                LVM_SUBITEMHITTEST = LVM_FIRST + 57,
                LVM_SETCOLUMNORDERARRAY= LVM_FIRST + 58,
                LVM_GETCOLUMNORDERARRAY= LVM_FIRST + 59,
                LVM_SETHOTITEM = LVM_FIRST + 60,
                LVM_GETHOTITEM = LVM_FIRST + 61,
                LVM_SETHOTCURSOR = LVM_FIRST + 62,
                LVM_GETHOTCURSOR = LVM_FIRST + 63,
                LVM_APPROXIMATEVIEWRECT= LVM_FIRST + 64,
                LVM_SETWORKAREAS = LVM_FIRST + 65,
                LVM_GETWORKAREAS = LVM_FIRST + 70,
                LVM_GETNUMBEROFWORKAREAS = LVM_FIRST + 73,
                LVM_GETSELECTIONMARK = LVM_FIRST + 66,
                LVM_SETSELECTIONMARK = LVM_FIRST + 67,
                LVM_SETHOVERTIME = LVM_FIRST + 71,
                LVM_GETHOVERTIME = LVM_FIRST + 72,
                LVM_SETTOOLTIPS = LVM_FIRST + 74,
                LVM_GETTOOLTIPS = LVM_FIRST + 78,
                LVM_SORTITEMSEX = LVM_FIRST + 81,
                LVM_SETBKIMAGEA = LVM_FIRST + 68,
                LVM_SETBKIMAGEW = LVM_FIRST + 138,
                LVM_GETBKIMAGEA = LVM_FIRST + 69,
                LVM_GETBKIMAGEW = LVM_FIRST + 139,
                LVM_SETSELECTEDCOLUMN = LVM_FIRST + 140,
                LVM_SETVIEW = LVM_FIRST + 142,
                LVM_GETVIEW = LVM_FIRST + 143,
                LVM_INSERTGROUP = LVM_FIRST + 145,
                LVM_SETGROUPINFO = LVM_FIRST + 147,
                LVM_GETGROUPINFO = LVM_FIRST + 149,
                LVM_REMOVEGROUP = LVM_FIRST + 150,
                LVM_MOVEGROUP = LVM_FIRST + 151,
                LVM_GETGROUPCOUNT = LVM_FIRST + 152,
                LVM_GETGROUPINFOBYINDEX = LVM_FIRST + 153,
                LVM_MOVEITEMTOGROUP = LVM_FIRST + 154,
                LVM_GETGROUPRECT = LVM_FIRST + 98,
                LVM_SETGROUPMETRICS = LVM_FIRST + 155,
                LVM_GETGROUPMETRICS = LVM_FIRST + 156,
                LVM_ENABLEGROUPVIEW = LVM_FIRST + 157,
                LVM_SORTGROUPS = LVM_FIRST + 158,
                LVM_INSERTGROUPSORTED = LVM_FIRST + 159,
                LVM_REMOVEALLGROUPS = LVM_FIRST + 160,
                LVM_HASGROUP = LVM_FIRST + 161,
                LVM_GETGROUPSTATE = LVM_FIRST + 92,
                LVM_GETFOCUSEDGROUP = LVM_FIRST + 93,
                LVM_SETTILEVIEWINFO = LVM_FIRST + 162,
                LVM_GETTILEVIEWINFO = LVM_FIRST + 163,
                LVM_SETTILEINFO = LVM_FIRST + 164,
                LVM_GETTILEINFO = LVM_FIRST + 165,
                LVM_SETINSERTMARK = LVM_FIRST + 166,
                LVM_GETINSERTMARK = LVM_FIRST + 167,
                LVM_INSERTMARKHITTEST = LVM_FIRST + 168,
                LVM_GETINSERTMARKRECT = LVM_FIRST + 169,
                LVM_SETINSERTMARKCOLOR = LVM_FIRST + 170,
                LVM_GETINSERTMARKCOLOR = LVM_FIRST + 171,
                LVM_SETINFOTIP = LVM_FIRST + 173,
                LVM_GETSELECTEDCOLUMN = LVM_FIRST + 174,
                LVM_ISGROUPVIEWENABLED = LVM_FIRST + 175,
                LVM_GETOUTLINECOLOR = LVM_FIRST + 176,
                LVM_SETOUTLINECOLOR = LVM_FIRST + 177,
                LVM_CANCELEDITLABEL = LVM_FIRST + 179,
                LVM_MAPINDEXTOID = LVM_FIRST + 180,
                LVM_MAPIDTOINDEX = LVM_FIRST + 181,
                LVM_ISITEMVISIBLE = LVM_FIRST + 182,
                LVM_GETEMPTYTEXT= LVM_FIRST + 204,
                LVM_GETFOOTERRECT= LVM_FIRST + 205,
                LVM_GETFOOTERINFO= LVM_FIRST + 206,
                LVM_GETFOOTERITEMRECT= LVM_FIRST + 207,
                LVM_GETFOOTERITEM= LVM_FIRST + 208,
                LVM_GETITEMINDEXRECT = LVM_FIRST + 209,
                LVM_SETITEMINDEXSTATE = LVM_FIRST + 210,
                LVM_GETNEXTITEMINDEX = LVM_FIRST + 211
            }

            [Flags()]
            public enum ListViewHitTestResult
            {
                LVHT_NOWHERE = 0x00000001,
                LVHT_ONITEMICON = 0x00000002,
                LVHT_ONITEMLABEL = 0x00000004,
                LVHT_ONITEMSTATEICON = 0x00000008,
                LVHT_ONITEM = (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON),
                LVHT_ABOVE = 0x00000008,
                LVHT_BELOW = 0x00000010,
                LVHT_TORIGHT = 0x00000020,
                LVHT_TOLEFT = 0x00000040,
                LVHT_EX_GROUP_HEADER = 0x10000000,
                LVHT_EX_GROUP_FOOTER = 0x20000000,
                LVHT_EX_GROUP_COLLAPSE = 0x40000000,
                LVHT_EX_GROUP_BACKGROUND = unchecked((int)0x80000000),
                LVHT_EX_GROUP_STATEICON = 0x01000000,
                LVHT_EX_GROUP_SUBSETLINK = 0x02000000,
                LVHT_EX_GROUP = (LVHT_EX_GROUP_BACKGROUND | LVHT_EX_GROUP_COLLAPSE | LVHT_EX_GROUP_FOOTER | LVHT_EX_GROUP_HEADER | LVHT_EX_GROUP_STATEICON | LVHT_EX_GROUP_SUBSETLINK),
                LVHT_EX_ONCONTENTS = 0x04000000, // On item AND not on the background
                LVHT_EX_FOOTER = 0x08000000
            }

            [Flags()]
            public enum HeaderHitTestResult
            {
                HHT_NOWHERE = 0x0001,
                HHT_ONHEADER = 0x0002,
                HHT_ONDIVIDER = 0x0004,
                HHT_ONDIVOPEN = 0x0008,
                HHT_ONFILTER = 0x0010,
                HHT_ONFILTERBUTTON = 0x0020,
                HHT_ABOVE = 0x0100,
                HHT_BELOW = 0x0200,
                HHT_TORIGHT = 0x0400,
                HHT_TOLEFT = 0x0800,
                HHT_ONITEMSTATEICON = 0x1000,
                HHT_ONDROPDOWN = 0x2000,
                HHT_ONOVERFLOW = 0x4000
            }
            
            #endregion

            #region Constants

            private const int LVM_FIRST = 0x1000;
            private const int HDM_FIRST = 0x1200;

            public const int HDI_FORMAT = 0x4;

            public const int HDF_STRING = 0x4000;
            public const int HDF_OWNERDRAW = 0x8000;

            public const int ODA_DRAWENTIRE = 0x1;
            public const int ODT_HEADER = 100;

            #endregion
        }
    }
}
